步骤 10:选择静态或共享库¶
在本节中,我们将展示如何使用 BUILD_SHARED_LIBS
变量来控制 add_library()
的默认行为,并允许控制如何构建没有显式类型(STATIC
、 SHARED
、 MODULE
或 OBJECT
)的库。
为了实现这一点,我们需要将 BUILD_SHARED_LIBS
添加到顶层 CMakeLists.txt
。 我们使用 option()
命令,因为它允许用户选择性地选择值应该是 ON
还是 OFF
。
CMakeLists.txt¶
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
接下来,我们需要为我们的静态库和共享库指定输出目录。
CMakeLists.txt¶
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
最后,更新 MathFunctions/MathFunctions.h
以使用 dll 导出定义
MathFunctions/MathFunctions.h¶
#if defined(_WIN32)
# if defined(EXPORTING_MYMATH)
# define DECLSPEC __declspec(dllexport)
# else
# define DECLSPEC __declspec(dllimport)
# endif
#else // non windows
# define DECLSPEC
#endif
namespace mathfunctions {
double DECLSPEC sqrt(double x);
}
此时,如果您构建所有内容,您可能会注意到链接失败,因为我们将没有位置无关代码的静态库与具有位置无关代码的库组合在一起。 解决此问题的方法是显式设置 SqrtLibrary 的 POSITION_INDEPENDENT_CODE
目标属性,使其在构建共享库时为 True
。
MathFunctions/CMakeLists.txt¶
# state that SqrtLibrary need PIC when the default is shared libraries
set_target_properties(SqrtLibrary PROPERTIES
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
定义 EXPORTING_MYMATH
,说明我们在 Windows 上构建时使用 declspec(dllexport)
。
MathFunctions/CMakeLists.txt¶
# define the symbol stating we are using the declspec(dllexport) when
# building on windows
target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
练习:我们修改了 MathFunctions.h
以使用 dll 导出定义。 使用 CMake 文档,您能找到一个辅助模块来简化此操作吗?